using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Domain;
using Nop.Core.Domain.Blogs;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Forums;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Logistics;
using Nop.Core.Domain.Messages;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Tax;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Forums;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Logistics;
using Nop.Services.Messages;
using Nop.Services.Orders;
using Nop.Services.Security;
using Nop.Services.Seo;
using Nop.Services.Stores;
using Nop.Services.Tasks;
using Nop.Services.Topics;
using Nop.Web.Extensions;
using Nop.Web.Framework.Localization;
using Nop.Web.Framework.Security;
using Nop.Web.Framework.Themes;
using Nop.Web.Framework.UI.Captcha;
using Nop.Web.Infrastructure.Cache;
using Nop.Web.Models.Catalog;
using Nop.Web.Models.Common;
using Nop.Web.Models.Topics;




namespace Nop.Web.Controllers
{
    public partial class CommonController : BaseNopController
    {
        #region Fields

        private readonly ICategoryService _categoryService;
        private readonly IProductService _productService;
        private readonly IManufacturerService _manufacturerService;
        private readonly ITopicService _topicService;
        private readonly ILanguageService _languageService;
        private readonly ICurrencyService _currencyService;
        private readonly ILocalizationService _localizationService;
        private readonly IWorkContext _workContext;
        private readonly IQueuedEmailService _queuedEmailService;
        private readonly IEmailAccountService _emailAccountService;
        private readonly ISitemapGenerator _sitemapGenerator;
        private readonly IThemeContext _themeContext;
        private readonly IThemeProvider _themeProvider;
        private readonly IForumService _forumservice;
        private readonly IGenericAttributeService _genericAttributeService;
        private readonly IWebHelper _webHelper;
        private readonly IPermissionService _permissionService;
        private readonly IMobileDeviceHelper _mobileDeviceHelper;
        private readonly HttpContextBase _httpContext;
        private readonly ICacheManager _cacheManager;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly IStoreService _storeService;
        private readonly Nop.Services.Logistics.IOrderProcessingService _orderProcessingService;
        private readonly IRegionService _regionService;
        private readonly ICustomerService _customerService;

        private readonly CustomerSettings _customerSettings;
        private readonly TaxSettings _taxSettings;
        private readonly CatalogSettings _catalogSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly EmailAccountSettings _emailAccountSettings;
        private readonly CommonSettings _commonSettings;
        private readonly BlogSettings _blogSettings;
        private readonly ForumSettings _forumSettings;
        private readonly LocalizationSettings _localizationSettings;
        private readonly CaptchaSettings _captchaSettings;
        private readonly ILogisticsService _logisticsService;
        private readonly LogisticsInformationSettings _logisticsInformationSettings;
        private readonly IInvoiceService _invoiceService;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IWorkflowMessageService _workflowMessageService;

        #endregion

        #region Constructors

        public CommonController(ICategoryService categoryService, IProductService productService,
            IManufacturerService manufacturerService, ITopicService topicService,
            ILanguageService languageService, IRegionService regionService,
            ICurrencyService currencyService, ILocalizationService localizationService,
            IWorkContext workContext, ICustomerService customerService,
            IQueuedEmailService queuedEmailService, IEmailAccountService emailAccountService,
            ISitemapGenerator sitemapGenerator, IThemeContext themeContext,
            IThemeProvider themeProvider, IForumService forumService,
            IGenericAttributeService genericAttributeService, IWebHelper webHelper,
            IPermissionService permissionService, IMobileDeviceHelper mobileDeviceHelper,
            HttpContextBase httpContext, ICacheManager cacheManager,
            ICustomerActivityService customerActivityService, IStoreService storeService,
            CustomerSettings customerSettings, Nop.Services.Logistics.IOrderProcessingService orderProcessingService,
            TaxSettings taxSettings, CatalogSettings catalogSettings,
            StoreInformationSettings storeInformationSettings, EmailAccountSettings emailAccountSettings,
            CommonSettings commonSettings, BlogSettings blogSettings, ForumSettings forumSettings,
            LocalizationSettings localizationSettings, CaptchaSettings captchaSettings,
            ILogisticsService logisticsService, LogisticsInformationSettings logisticsInformationSettings,
            IInvoiceService invoiceService, IShoppingCartService shoppingCartService, IWorkflowMessageService workflowMessageService)
        {
            this._categoryService = categoryService;
            this._productService = productService;
            this._manufacturerService = manufacturerService;
            this._topicService = topicService;
            this._languageService = languageService;
            this._currencyService = currencyService;
            this._localizationService = localizationService;
            this._workContext = workContext;
            this._queuedEmailService = queuedEmailService;
            this._emailAccountService = emailAccountService;
            this._sitemapGenerator = sitemapGenerator;
            this._themeContext = themeContext;
            this._themeProvider = themeProvider;
            this._forumservice = forumService;
            this._genericAttributeService = genericAttributeService;
            this._webHelper = webHelper;
            this._regionService = regionService;
            this._permissionService = permissionService;
            this._mobileDeviceHelper = mobileDeviceHelper;
            this._httpContext = httpContext;
            this._cacheManager = cacheManager;
            this._customerActivityService = customerActivityService;
            this._customerService = customerService;
            this._storeService = storeService;
            this._orderProcessingService = orderProcessingService;
            this._customerSettings = customerSettings;
            this._regionService = regionService;
            this._taxSettings = taxSettings;
            this._catalogSettings = catalogSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._emailAccountSettings = emailAccountSettings;
            this._commonSettings = commonSettings;
            this._blogSettings = blogSettings;
            this._forumSettings = forumSettings;
            this._localizationSettings = localizationSettings;
            this._captchaSettings = captchaSettings;
            this._logisticsService = logisticsService;
            this._logisticsInformationSettings = logisticsInformationSettings;
            this._invoiceService = invoiceService;
            this._customerService = customerService;
            this._shoppingCartService = shoppingCartService;
            this._workflowMessageService = workflowMessageService;
        }

        #endregion

        #region Utilities

        [NonAction]
        protected LanguageSelectorModel PrepareLanguageSelectorModel()
        {
            var availableLanguages = _cacheManager.Get(ModelCacheEventConsumer.AVAILABLE_LANGUAGES_MODEL_KEY, () =>
            {
                var result = _languageService
                    .GetAllLanguages()
                    .Select(x => new LanguageModel()
                    {
                        Id = x.Id,
                        Name = x.Name,
                        FlagImageFileName = x.FlagImageFileName,
                    })
                    .ToList();
                return result;
            });

            var model = new LanguageSelectorModel()
            {
                CurrentLanguageId = _workContext.WorkingLanguage.Id,
                AvailableLanguages = availableLanguages,
                UseImages = _localizationSettings.UseImagesForLanguageSelection
            };
            return model;
        }

        [NonAction]
        protected CurrencySelectorModel PrepareCurrencySelectorModel()
        {
            var availableCurrencies = _cacheManager.Get(string.Format(ModelCacheEventConsumer.AVAILABLE_CURRENCIES_MODEL_KEY, _workContext.WorkingLanguage.Id), () =>
            {
                var result = _currencyService
                    .GetAllCurrencies()
                    .Select(x => new CurrencyModel()
                    {
                        Id = x.Id,
                        Name = x.GetLocalized(y => y.Name),
                    })
                    .ToList();
                return result;
            });

            var model = new CurrencySelectorModel()
            {
                CurrentCurrencyId = _workContext.WorkingCurrency.Id,
                AvailableCurrencies = availableCurrencies
            };
            return model;
        }

        [NonAction]
        protected TaxTypeSelectorModel PrepareTaxTypeSelectorModel()
        {
            var model = new TaxTypeSelectorModel()
            {
                Enabled = _taxSettings.AllowCustomersToSelectTaxDisplayType,
                CurrentTaxType = _workContext.TaxDisplayType
            };
            return model;
        }

        [NonAction]
        protected int GetUnreadPrivateMessages()
        {
            var result = 0;
            var customer = _workContext.CurrentCustomer;
            if (_forumSettings.AllowPrivateMessages && !customer.IsGuest())
            {
                var privateMessages = _forumservice.GetAllPrivateMessages(0, customer.Id, false, null, false, string.Empty, 0, 1);

                if (privateMessages.TotalCount > 0)
                {
                    result = privateMessages.TotalCount;
                }
            }

            return result;
        }

        #endregion

        #region Methods

        //language
        [ChildActionOnly]
        public ActionResult LanguageSelector()
        {
            var model = PrepareLanguageSelectorModel();
            return PartialView(model);
        }
        public ActionResult SetLanguage(int langid, string returnUrl = "")
        {
            var language = _languageService.GetLanguageById(langid);
            if (language != null && language.Published)
            {
                _workContext.WorkingLanguage = language;
            }

            //url referrer
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = _webHelper.GetUrlReferrer();
            //home page
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = Url.RouteUrl("HomePage");
            if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
            {
                string applicationPath = HttpContext.Request.ApplicationPath;
                if (returnUrl.IsLocalizedUrl(applicationPath, true))
                {
                    //already localized URL
                    returnUrl = returnUrl.RemoveLanguageSeoCodeFromRawUrl(applicationPath);
                }
                returnUrl = returnUrl.AddLanguageSeoCodeToRawUrl(applicationPath, _workContext.WorkingLanguage);
            }
            return Redirect(returnUrl);
        }

        //region
        [ChildActionOnly]
        public ActionResult RegionSelector()
        {
            var model = PrepareRegionSelectorModel();

            return PartialView(model);
        }

        public ActionResult SetRegion(int regionId, string returnUrl = "")
        {
            var region = _regionService.GetRegionById(regionId);
            if (region != null && _workContext.CurrentCustomer.Region.Id != regionId)
            {
                _workContext.CurrentCustomer.Region = region;
                _customerService.UpdateCustomer(_workContext.CurrentCustomer);
            }
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = _webHelper.GetUrlReferrer();
            //home page
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = Url.RouteUrl("HomePage");
            return Redirect(returnUrl);
        }

        [NonAction]
        private RegionSelectorModel PrepareRegionSelectorModel()
        {
            var availableRegions = _cacheManager.Get(ModelCacheEventConsumer.AVAILABLE_REGIONS_MODEL_KEY, () =>
            {
                var result = _regionService.GetAllRegions()
                    .Select(x => new RegionModel()
                    {
                        RegionId = x.Id,
                        Name = x.Name
                    })
                    .ToList();
                return result;
            });

            var model = new RegionSelectorModel()
            {
                AvailableRegions = availableRegions
            };
            return model;
        }

        //currency
        [ChildActionOnly]
        public ActionResult CurrencySelector()
        {
            var model = PrepareCurrencySelectorModel();
            return PartialView(model);
        }
        public ActionResult CurrencySelected(int customerCurrency, string returnUrl = "")
        {
            var currency = _currencyService.GetCurrencyById(customerCurrency);
            if (currency != null)
                _workContext.WorkingCurrency = currency;

            //url referrer
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = _webHelper.GetUrlReferrer();
            //home page
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = Url.RouteUrl("HomePage");
            return Redirect(returnUrl);
        }

        //tax type
        [ChildActionOnly]
        public ActionResult TaxTypeSelector()
        {
            var model = PrepareTaxTypeSelectorModel();
            return PartialView(model);
        }
        public ActionResult TaxTypeSelected(int customerTaxType, string returnUrl = "")
        {
            var taxDisplayType = (TaxDisplayType)Enum.ToObject(typeof(TaxDisplayType), customerTaxType);
            _workContext.TaxDisplayType = taxDisplayType;

            //url referrer
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = _webHelper.GetUrlReferrer();
            //home page
            if (String.IsNullOrEmpty(returnUrl))
                returnUrl = Url.RouteUrl("HomePage");
            return Redirect(returnUrl);
        }

        //Configuration page (used on mobile devices)
        [ChildActionOnly]
        public ActionResult ConfigButton()
        {
            var langModel = PrepareLanguageSelectorModel();
            var currModel = PrepareCurrencySelectorModel();
            var taxModel = PrepareTaxTypeSelectorModel();
            //should we display the button?
            if (langModel.AvailableLanguages.Count > 1 ||
                currModel.AvailableCurrencies.Count > 1 ||
                taxModel.Enabled)
                return PartialView();
            else
                return Content("");
        }
        public ActionResult Config()
        {
            return View();
        }

        //footer
        [ChildActionOnly]
        public ActionResult JavaScriptDisabledWarning()
        {
            if (!_commonSettings.DisplayJavaScriptDisabledWarning)
                return Content("");

            return PartialView();
        }

        public ActionResult UserLinks()
        {
            var customer = _workContext.CurrentCustomer;
            var customerEmailUsername = "";
            if (customer.IsRegistered())
            {
                if (_customerSettings.UsernamesEnabled)
                {
                    customerEmailUsername = customer.Username;
                }
                else
                {
                    customerEmailUsername = customer.GetFullName();
                    if (String.IsNullOrWhiteSpace(customerEmailUsername))
                    {
                        customerEmailUsername = customer.Email;
                    }
                }
            }
            else
            {
                customerEmailUsername = _localizationService.GetResource("Common.Guest");
            }
            var model = new UserLinksModel()
            {
                IsAuthenticated = customer.IsRegistered(),
                CustomerEmailUsername = customerEmailUsername,
                DisplayAdminLink = _permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel),
                IsCustomerImpersonated = _workContext.OriginalCustomerIfImpersonated != null,
                HideTracking = !_customerSettings.AlwaysShowTrackingTab && !HasTrackingPackages(customer),
                HideInvoices = !_customerSettings.AlwaysShowInvoiceTab && _invoiceService.GetInvoicesByCustomerId(customer.Id).Count < 1,
            };
            return PartialView(model);
        }

        [NonAction]
        protected bool HasTrackingPackages(Customer customer)
        {
            var pkgs = _logisticsService.SearchTrackingPackages(
                customer.Id,
                null,
                null,
                null,
                0,
                1,
                _logisticsInformationSettings.TrackingIncludeDelivered); // Just peek the first one;
            return pkgs.TotalCount > 0;
        }

        //[OutputCacheAttribute(VaryByParam = "*", Duration = 10)]
        public ActionResult HeaderLinks(bool showMenu = true, bool isCheckout = false)
        {
            var customer = _workContext.CurrentCustomer;

            var unreadMessageCount = GetUnreadPrivateMessages();
            var unreadMessage = string.Empty;
            var alertMessage = string.Empty;
            if (unreadMessageCount > 0)
            {
                unreadMessage = string.Format(_localizationService.GetResource("PrivateMessages.TotalUnread"), unreadMessageCount);

                //notifications here
                if (_forumSettings.ShowAlertForPM &&
                    !customer.GetAttribute<bool>(SystemCustomerAttributeNames.NotifiedAboutNewPrivateMessages))
                {
                    _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.NotifiedAboutNewPrivateMessages, true);
                    alertMessage = string.Format(_localizationService.GetResource("PrivateMessages.YouHaveUnreadPM"), unreadMessageCount);
                }
            }

            var customerEmailUsername = "";
            if (customer.IsRegistered())
            {
                if (_customerSettings.UsernamesEnabled)
                {
                    customerEmailUsername = customer.Username;
                }
                else
                {
                    customerEmailUsername = customer.GetFullName();
                    if (String.IsNullOrWhiteSpace(customerEmailUsername))
                    {
                        customerEmailUsername = customer.Email;
                    }
                }
            }
            else
            {
                customerEmailUsername = _localizationService.GetResource("Customer.Guest");
            }

            var model = new HeaderLinksModel()
            {
                IsAuthenticated = customer.IsRegistered(),
                CustomerEmailUsername = customerEmailUsername,
                IsCustomerImpersonated = _workContext.OriginalCustomerIfImpersonated != null,
                DisplayAdminLink = _permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel),
                ShoppingCartEnabled = _permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) && !isCheckout,
                ShoppingCartItems = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList().GetTotalProducts(),
                WishlistEnabled = _permissionService.Authorize(StandardPermissionProvider.EnableWishlist),
                WishlistItems = customer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist).ToList().GetTotalProducts(),
                FavoriteStoreEnabled = true,
                FavoriteStores = _storeService.GetFavoriteStores(customer).Count,
                AllowPrivateMessages = _forumSettings.AllowPrivateMessages,
                UnreadPrivateMessages = unreadMessage,
                AlertMessage = alertMessage,
                HasPendingShippingOrder = _orderProcessingService.HasPendingOrders(customer),
                ShowMenu = showMenu,
                IsRegionSelected = customer.Region != null,
                IsCurrencySelected = customer.CurrencyId != null
            };

            //Get all currency
            var currencies = _currencyService.GetAllCurrencies();
            //if (customer.CurrencyId == null)
            //{
            //    var notSpecified = _localizationService.GetLocaleStringResourceByName("Common.NotSpecified", 1);
            //    if (notSpecified != null)
            //    {
            //        model.AvailableCurrencies.Add(new SelectListItem()
            //        {
            //            Text = notSpecified.ResourceValue,
            //            Value = "0",
            //            Selected = true
            //        });
            //    }

            //}
            foreach (var currency in currencies)
            {
                //SelectListItem item = new SelectListItem();
                //item.Text = currency.Name;
                //item.Value = currency.Id.ToString();
                //item.Selected  = customer.Currency != null && customer.Currency.Id == currency.Id;
                //model.AvailableCurrencies.Add(item);
                model.AvailableCurrencies.Add(new SelectListItem()
                {
                    Text = currency.Name,
                    Value = currency.Id.ToString(),
                    Selected = customer.Currency != null && customer.Currency.Id == currency.Id
                });
            }
            model.SelectedCurrency = customer.Currency != null ? customer.Currency.Id : 0;

            //region
            var regions = _regionService.GetAllRegions();
            if (customer.Region == null)
            {
                var notSpecified = _localizationService.GetLocaleStringResourceByName("Common.NotSpecified", 1);
                if (notSpecified != null)
                {
                    model.AvailableRegions.Add(new SelectListItem()
                    {
                        Text = notSpecified.ResourceValue,
                        Value = "0",
                        Selected = true
                    });
                }
            }
            foreach (var region in regions)
            {
                model.AvailableRegions.Add(new SelectListItem()
                {
                    Text = region.Name,
                    Value = region.Id.ToString(),
                    Selected = customer.Region != null && customer.Region.Id == region.Id
                });
            }
            model.SelectedRegion = customer.Region != null ? customer.Region.Id : 0;

            return PartialView(model);
        }


        #region Change Customer Currency
        /// <summary>
        /// 
        /// </summary>
        /// <param name="CurrencyId"></param>
        /// <returns></returns>
        public ActionResult ChangeCustomerCurrency(int selectedCurrency, string returnUrl = "/")
        {
            if (_workContext.CurrentCustomer != null)
            {
                Customer customer = _workContext.CurrentCustomer;
                customer.CurrencyId = selectedCurrency;
                _customerService.UpdateCustomer(customer);
            }
            return Redirect(returnUrl);
        }
        #endregion
        /// <summary>
        /// Change current region
        /// </summary>
        /// <param name="selectedRegion">Selected Region Id</param>
        /// <param name="returnUrl">a return url that the page will redirect</param>
        /// <returns></returns>
        public ActionResult RegionChange(int selectedRegion, string returnUrl = "/")
        {
            var customer = _workContext.CurrentCustomer;
            if (selectedRegion > 0)
            {
                if (customer == null) return Redirect(returnUrl);

                var region = _regionService.GetRegionById(selectedRegion);

                if (region == null) return Redirect(returnUrl);

                if (customer.Region == null || customer.Region.Id != selectedRegion)
                {
                    customer.Region = region;

                    var countryCode = _logisticsService.GetDistrictById(region.Id).CountryCode;
                    customer.Currency = _currencyService.GetAllCurrencies(true).FirstOrDefault(x => x.CountryCode == countryCode);
                    _customerService.UpdateCustomer(customer);
                    var cart = _workContext.CurrentCustomer.ShoppingCartItems
                               .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();
                    foreach (var item in cart)
                    {
                        _shoppingCartService.DeleteShoppingCartItem(item);
                    }
                }
            }
            else
            {
                customer.Region = null;
                _customerService.UpdateCustomer(customer);
            }
            return Redirect(returnUrl);
        }

        //header
        [ChildActionOnly]
        public ActionResult Header()
        {
            var model = new HeaderLinksModel()
            {
            };

            return PartialView(model);
        }

        [ChildActionOnly]
        public ActionResult HeaderLogo()
        {
            return PartialView();
        }

        [ChildActionOnly]
        public ActionResult HeaderMenu()
        {
            return PartialView();
        }

        //footer
        [ChildActionOnly]
        public ActionResult Footer()
        {
            var model = new FooterModel()
            {
                StoreName = _storeInformationSettings.StoreName
            };

            return PartialView(model);
        }

        [ChildActionOnly]
        public ActionResult FooterNoTopic()
        {
            var model = new FooterModel()
            {
                StoreName = _storeInformationSettings.StoreName
            };

            return PartialView(model);
        }

        [ChildActionOnly]
        public ActionResult FooterBadge()
        {
            return PartialView();
        }

        //menu
        [ChildActionOnly]
        public ActionResult Menu()
        {
            var model = new MenuModel()
            {
                RecentlyAddedProductsEnabled = _catalogSettings.RecentlyAddedProductsEnabled,
                BlogEnabled = _blogSettings.Enabled,
                ForumEnabled = _forumSettings.ForumsEnabled
            };

            return PartialView(model);
        }

        //info block
        [ChildActionOnly]
        public ActionResult InfoBlock()
        {
            var model = new InfoBlockModel()
            {
                RecentlyAddedProductsEnabled = _catalogSettings.RecentlyAddedProductsEnabled,
                RecentlyViewedProductsEnabled = _catalogSettings.RecentlyViewedProductsEnabled,
                CompareProductsEnabled = _catalogSettings.CompareProductsEnabled,
                BlogEnabled = _blogSettings.Enabled,
                SitemapEnabled = _commonSettings.SitemapEnabled,
                ForumEnabled = _forumSettings.ForumsEnabled,
                AllowPrivateMessages = _forumSettings.AllowPrivateMessages,
            };

            return PartialView(model);
        }

        public ActionResult InfoBlockFront()
        {
            var model = new InfoBlockModel()
            {
                RecentlyAddedProductsEnabled = _catalogSettings.RecentlyAddedProductsEnabled,
                RecentlyViewedProductsEnabled = _catalogSettings.RecentlyViewedProductsEnabled,
                CompareProductsEnabled = _catalogSettings.CompareProductsEnabled,
                BlogEnabled = _blogSettings.Enabled,
                SitemapEnabled = _commonSettings.SitemapEnabled,
                ForumEnabled = _forumSettings.ForumsEnabled,
                AllowPrivateMessages = _forumSettings.AllowPrivateMessages,
            };

            return PartialView(model);
        }

        //contact us page
        [NopHttpsRequirement(SslRequirement.No)]
        public ActionResult ContactUs()
        {
            var model = new ContactUsModel()
            {
                Email = _workContext.CurrentCustomer.Email,
                FullName = _workContext.CurrentCustomer.GetFullName(),
                DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnContactUsPage
            };
            return View(model);
        }
        [HttpPost, ActionName("ContactUs")]
        [CaptchaValidator]
        public ActionResult ContactUsSend(ContactUsModel model, bool captchaValid, string Phone = "")
        {
            //validate CAPTCHA, if available
            if (_captchaSettings.Enabled && _captchaSettings.ShowOnContactUsPage && !captchaValid)
            {
                ModelState.AddModelError("", _localizationService.GetResource("Common.WrongCaptcha"));
            }

            if (ModelState.IsValid)
            {
                //send email
                SendEmail(model);

                model.SuccessfullySent = true;
                model.Result = _localizationService.GetResource("ContactUs.YourEnquiryHasBeenSent");

                //activity log
                _customerActivityService.InsertActivity("PublicStore.ContactUs", _localizationService.GetResource("ActivityLog.PublicStore.ContactUs"));

                return View(model);
            }

            model.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnContactUsPage;
            return View(model);
        }

        /// <summary>
        /// send email
        /// </summary>
        /// <param name="model">message model</param>
        private void SendEmail(ContactUsModel model)
        {
            var emailAccount = _emailAccountService.GetEmailAccountById(_emailAccountSettings.DefaultEmailAccountId) ??
                                _emailAccountService.GetAllEmailAccounts().FirstOrDefault();

            var useEmail = model.Email.Trim();
            var fullName = model.FullName;

            var body = Core.Html.HtmlHelper.FormatText(model.Enquiry, false, true, false, false, false, false);
            //customer send email to spotsHUB
            _workflowMessageService.SendContactUsMessageEmail(_workContext.CurrentCustomer, 1, emailAccount, useEmail, fullName, body);
            //spotsHUB send confirm email to customer
            _workflowMessageService.SendContactUsConfirmEmail(_workContext.CurrentCustomer, 1, emailAccount, useEmail, fullName, string.Empty);
        }

        [NopHttpsRequirement(SslRequirement.No)]
        public ActionResult Sitemap()
        {
            if (!_commonSettings.SitemapEnabled)
                return RedirectToRoute("HomePage");

            var model = new SitemapModel();
            if (_commonSettings.SitemapIncludeCategories)
            {
                var categories = _categoryService.GetAllCategories();
                model.Categories = categories.Select(x => x.ToModel()).ToList();
            }
            if (_commonSettings.SitemapIncludeManufacturers)
            {
                var manufacturers = _manufacturerService.GetAllManufacturers();
                model.Manufacturers = manufacturers.Select(x => x.ToModel()).ToList();
            }
            if (_commonSettings.SitemapIncludeProducts)
            {
                //limit product to 200 until paging is supported on this page
                IList<int> filterableSpecificationAttributeOptionIds = null;
                var products = _productService.SearchProducts(0, 0, 0, null, null, null, 0, null, false, false, 0, null,
                     ProductSortingEnum.Position, 0, 200,
                     false, out filterableSpecificationAttributeOptionIds);
                model.Products = products.Select(product => new ProductOverviewModel()
                {
                    Id = product.Id,
                    Name = product.GetLocalized(x => x.Name),
                    ShortDescription = product.GetLocalized(x => x.ShortDescription),
                    FullDescription = product.GetLocalized(x => x.FullDescription),
                    SeName = product.GetSeName(),
                }).ToList();
            }
            if (_commonSettings.SitemapIncludeTopics)
            {
                var topics = _topicService.GetAllTopics().ToList().FindAll(t => t.IncludeInSitemap);
                model.Topics = topics.Select(topic => new TopicModel()
                {
                    Id = topic.Id,
                    SystemName = topic.SystemName,
                    IncludeInSitemap = topic.IncludeInSitemap,
                    IsPasswordProtected = topic.IsPasswordProtected,
                    Title = topic.GetLocalized(x => x.Title),
                })
                .ToList();
            }
            return View(model);
        }

        //SEO sitemap page
        [NopHttpsRequirement(SslRequirement.No)]
        public ActionResult SitemapSeo()
        {
            if (!_commonSettings.SitemapEnabled)
                return RedirectToRoute("HomePage");

            string siteMap = _sitemapGenerator.Generate();
            return Content(siteMap, "text/xml");
        }

        //store theme
        [ChildActionOnly]
        public ActionResult StoreThemeSelector()
        {
            if (!_storeInformationSettings.AllowCustomerToSelectTheme)
                return Content("");

            var model = new StoreThemeSelectorModel();
            var currentTheme = _themeProvider.GetThemeConfiguration(_themeContext.WorkingDesktopTheme);
            model.CurrentStoreTheme = new StoreThemeModel()
            {
                Name = currentTheme.ThemeName,
                Title = currentTheme.ThemeTitle
            };
            model.AvailableStoreThemes = _themeProvider.GetThemeConfigurations()
                //do not display themes for mobile devices
                .Where(x => !x.MobileTheme)
                .Select(x =>
                {
                    return new StoreThemeModel()
                    {
                        Name = x.ThemeName,
                        Title = x.ThemeTitle
                    };
                })
                .ToList();
            return PartialView(model);
        }
        public ActionResult StoreThemeSelected(string themeName)
        {
            _themeContext.WorkingDesktopTheme = themeName;

            var model = new StoreThemeSelectorModel();
            var currentTheme = _themeProvider.GetThemeConfiguration(_themeContext.WorkingDesktopTheme);
            model.CurrentStoreTheme = new StoreThemeModel()
            {
                Name = currentTheme.ThemeName,
                Title = currentTheme.ThemeTitle
            };
            model.AvailableStoreThemes = _themeProvider.GetThemeConfigurations()
                //do not display themes for mobile devices
                .Where(x => !x.MobileTheme)
                .Select(x =>
                {
                    return new StoreThemeModel()
                    {
                        Name = x.ThemeName,
                        Title = x.ThemeTitle
                    };
                })
                .ToList();
            return PartialView("StoreThemeSelector", model);
        }

        //favicon
        [ChildActionOnly]
        public ActionResult Favicon()
        {
            var model = new FaviconModel()
            {
                Uploaded = System.IO.File.Exists(System.IO.Path.Combine(Request.PhysicalApplicationPath, "favicon.ico")),
                FaviconUrl = _webHelper.GetStoreLocation() + "favicon.ico"
            };

            return PartialView(model);
        }

        /// <summary>
        /// Change presentation layer (desktop or mobile version)
        /// </summary>
        /// <param name="dontUseMobileVersion">True - use desktop version; false - use version for mobile devices</param>
        /// <returns>Action result</returns>
        public ActionResult ChangeDevice(bool dontUseMobileVersion)
        {
            _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer,
                SystemCustomerAttributeNames.DontUseMobileVersion, dontUseMobileVersion);

            string returnurl = _webHelper.GetUrlReferrer();
            if (String.IsNullOrEmpty(returnurl))
                returnurl = Url.RouteUrl("HomePage");
            return Redirect(returnurl);
        }
        [ChildActionOnly]
        public ActionResult ChangeDeviceBlock()
        {
            if (!_mobileDeviceHelper.MobileDevicesSupported())
                //mobile devices support is disabled
                return Content("");

            if (!_mobileDeviceHelper.IsMobileDevice(_httpContext))
                //request is made by a desktop computer
                return Content("");

            return View();
        }

        //EU Cookie law
        [ChildActionOnly]
        public ActionResult EuCookieLaw()
        {
            if (!_storeInformationSettings.DisplayEuCookieLawWarning)
                //disabled
                return Content("");

            if (_workContext.CurrentCustomer.GetAttribute<bool>("EuCookieLaw.Accepted"))
                //already accepted
                return Content("");

            return PartialView();
        }
        [HttpPost]
        public ActionResult EuCookieLawAccept()
        {
            if (!_storeInformationSettings.DisplayEuCookieLawWarning)
                //disabled
                return Json(new { stored = false });

            //save setting
            _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, "EuCookieLaw.Accepted", true);
            return Json(new { stored = true });
        }

        public ActionResult RobotsTextFile()
        {
            var disallowPaths = new List<string>()
                                    {
                                        "/bin/",
                                        "/content/files/",
                                        "/content/files/exportimport/",
                                        "/country/getstatesbycountryid",
                                        "/install",
                                        "/setproductreviewhelpfulness",
                                    };
            var localizableDisallowPaths = new List<string>()
                                               {
                                                   "/boards/forumwatch",
                                                   "/boards/postedit",
                                                   "/boards/postdelete",
                                                   "/boards/postcreate",
                                                   "/boards/topicedit",
                                                   "/boards/topicdelete",
                                                   "/boards/topiccreate",
                                                   "/boards/topicmove",
                                                   "/boards/topicwatch",
                                                   "/cart",
                                                   "/checkout",
                                                   "/checkout/billingaddress",
                                                   "/checkout/completed",
                                                   "/checkout/confirm",
                                                   "/checkout/shippingaddress",
                                                   "/checkout/shippingmethod",
                                                   "/checkout/paymentinfo",
                                                   "/checkout/paymentmethod",
                                                   "/clearcomparelist",
                                                   "/compareproducts",
                                                   "/customer/avatar",
                                                   "/customer/activation",
                                                   "/customer/addresses",
                                                   "/customer/backinstocksubscriptions",
                                                   "/customer/changepassword",
                                                   "/customer/checkusernameavailability",
                                                   "/customer/downloadableproducts",
                                                   "/customer/forumsubscriptions",
                                                   "/customer/info",
                                                   "/customer/orders",
                                                   "/customer/returnrequests",
                                                   "/customer/rewardpoints",
                                                   "/deletepm",
                                                   "/emailwishlist",
                                                   "/inboxupdate",
                                                   "/newsletter/subscriptionactivation",
                                                   "/onepagecheckout",
                                                   "/orderdetails",
                                                   "/passwordrecovery/confirm",
                                                   "/poll/vote",
                                                   "/privatemessages",
                                                   "/returnrequest",
                                                   "/sendpm",
                                                   "/sentupdate",
                                                   "/subscribenewsletter",
                                                   "/topic/authenticate",
                                                   "/viewpm",
                                                   "/wishlist",
                                               };


            const string newLine = "\r\n"; //Environment.NewLine
            var sb = new StringBuilder();
            sb.Append("User-agent: *");
            sb.Append(newLine);
            //usual paths
            foreach (var path in disallowPaths)
            {
                sb.AppendFormat("Disallow: {0}", path);
                sb.Append(newLine);
            }
            //localizable paths (without SEO code)
            foreach (var path in localizableDisallowPaths)
            {
                sb.AppendFormat("Disallow: {0}", path);
                sb.Append(newLine);
            }
            if (_localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
            {
                //URLs are localizable. Append SEO code
                foreach (var language in _languageService.GetAllLanguages())
                {
                    foreach (var path in localizableDisallowPaths)
                    {
                        sb.AppendFormat("Disallow: {0}{1}", language.UniqueSeoCode, path);
                        sb.Append(newLine);
                    }
                }
            }

            Response.ContentType = "text/plain";
            Response.Write(sb.ToString());
            return null;
        }

        public ActionResult GenericUrl()
        {
            //seems that no entity was found
            return RedirectToRoute("HomePage");
        }

        //store is closed
        public ActionResult StoreClosed()
        {
            return RedirectToRoute("HomePage");
        }

        #endregion
    }
}
